//
//  ViewController.m
//  JsonTool
//
//  Created by gugubo on 2017/4/21.
//  Copyright © 2017年 gugubo. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) NSMutableArray *hNameArray;
@property (strong, nonatomic) NSMutableArray *mNameArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)controlTextDidChange:(NSNotification *)obj{
    [self textDidChange:nil];
}

- (void)textDidChange:(NSNotification *)notification{
    NSData *jsonData = [self.inputTextView.string dataUsingEncoding:NSUTF8StringEncoding];
    
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    [self.hNameArray removeAllObjects];
    [self.mNameArray removeAllObjects];
    
    self.outputHTextView.string = [self setupHFileWithDict:dic modelName:self.textField.stringValue];
    self.outputMTextView.string = [self setupMFileWithDict:dic modelName:self.textField.stringValue];
}

- (NSString *)setupHFileWithDict:(NSDictionary *)dict modelName:(NSString *)modelName{
    if (!modelName.length) {
        modelName = @"Model";
    }
    
    if ([self.hNameArray containsObject:modelName]) {
        return @"";
    }
    
    [self.hNameArray addObject:modelName];
    
    NSString *string = [NSString stringWithFormat:@"@interface %@ : NSObject\n\n",modelName];
    
    NSString *propertyString = @"", *modelString = @"";
    NSMutableArray *mArray = [[NSMutableArray alloc] init];
    
    for (NSString *key in [dict allKeys]) {
        NSString *pLineString;
        id obj = [dict objectForKey:key];
        NSString *valueKey = [self.textField.stringValue stringByAppendingString:key];
        
        if ([obj isKindOfClass:[NSDictionary class]]) {
            [mArray addObject:[self setupHFileWithDict:obj modelName:valueKey]];
            pLineString = [NSString stringWithFormat:@"@property (strong, nonatomic) %@ *%@;\n",valueKey,key];
        }else if ([obj isKindOfClass:[NSArray class]]){
            if ([obj count] && [[obj firstObject] isKindOfClass:[NSDictionary class]]) {
                [mArray addObject:[self setupHFileWithDict:[obj firstObject] modelName:valueKey]];
            }
            pLineString = [NSString stringWithFormat:@"@property (strong, nonatomic) NSArray *%@;\n",key];
        }else if ([obj isKindOfClass:[NSString class]]){
            pLineString = [NSString stringWithFormat:@"@property (copy, nonatomic) NSString *%@;\n",key];
        }else if ([obj isKindOfClass:[NSNumber class]]){
            
            NSNumber *number = obj;
            const char *objCType = [number objCType];
            
            if (strcmp(objCType, @encode(int)) == 0 ||
                strcmp(objCType, @encode(long)) == 0) {
                pLineString = [NSString stringWithFormat:@"@property (assign, nonatomic) NSInteger %@;\n",key];
            }else if (strcmp(objCType, @encode(unsigned int)) == 0 ||
                      strcmp(objCType, @encode(unsigned long)) == 0) {
                pLineString = [NSString stringWithFormat:@"@property (assign, nonatomic) NSUInteger %@;\n",key];
            }else if (strcmp(objCType, @encode(bool)) == 0 ||
                      strcmp(objCType, @encode(BOOL)) == 0){
                pLineString = [NSString stringWithFormat:@"@property (assign, nonatomic) BOOL %@;\n",key];
            }else if (strcmp(objCType, @encode(float)) == 0) {
                pLineString = [NSString stringWithFormat:@"@property (assign, nonatomic) CGFloat %@;\n",key];
            }else if (strcmp(objCType, @encode(double)) == 0){
                pLineString = [NSString stringWithFormat:@"@property (assign, nonatomic) double %@;\n",key];
            }else{
                pLineString = [NSString stringWithFormat:@"@property (strong, nonatomic) NSNumber *%@;\n",key];
            }
        }else{
            pLineString = [NSString stringWithFormat:@"@property (copy, nonatomic) NSString *%@;\n",key];
        }
        propertyString = [propertyString stringByAppendingString:pLineString];
    }
    
    NSString *endString = @"\n@end\n\n";
    
    for (NSString *modelStr in mArray) {
        modelString = [modelString stringByAppendingString:modelStr];
    }
    
    NSString *hFileString = [NSString stringWithFormat:@"%@%@%@%@",modelString,string,propertyString,endString];
    
    return hFileString;
}

- (NSString *)setupMFileWithDict:(NSDictionary *)dict modelName:(NSString *)modelName{
    if (!modelName.length) {
        modelName = @"Model";
    }
    
    if ([self.mNameArray containsObject:modelName]) {
        return @"";
    }
    
    [self.mNameArray addObject:modelName];
    
    NSString *string = [NSString stringWithFormat:@"@implementation %@\n",modelName];
    
    NSMutableArray *mArray = [[NSMutableArray alloc] init];
    NSMutableArray *fundArray = [[NSMutableArray alloc] init];
    
    for (NSString *key in [dict allKeys]) {
        id obj = [dict objectForKey:key];
        NSString *valueKey = [self.textField.stringValue stringByAppendingString:key];
        
        if ([obj isKindOfClass:[NSDictionary class]]) {
            [mArray addObject:[self setupMFileWithDict:obj modelName:valueKey]];
        }else if ([obj isKindOfClass:[NSArray class]]){
            NSObject *object = [obj firstObject];
            
            if ([obj count] && [object isKindOfClass:[NSDictionary class]]) {
                [mArray addObject:[self setupMFileWithDict:(NSDictionary *)object modelName:valueKey]];
                [fundArray addObject:key];
            }
        }
    }
    
    NSString *modelString = @"", *fundString = @"";
    
    for (NSString *modelStr in mArray) {
        modelString = [modelString stringByAppendingString:modelStr];
    }
    
    NSInteger count = fundArray.count;
    
    for (int i = 0; i < count; i++) {
        NSString *keyString = fundArray[i];
        
        if (fundString.length) {
            fundString = [fundString stringByAppendingString:@","];
        }
        NSString *valueKey = [self.textField.stringValue stringByAppendingString:keyString];
        NSString *dictString = [NSString stringWithFormat:@"@\"%@\":%@.class",keyString,valueKey];
        fundString = [fundString stringByAppendingString:dictString];
    }
    
    if (fundString.length) {
        fundString = [NSString stringWithFormat:@"\n+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass{\n    return @{%@};\n}\n",fundString];
    }
    
    NSString *endString = @"\n@end\n\n";
    
    NSString *mFileString = [NSString stringWithFormat:@"%@%@%@%@",modelString,string,fundString,endString];
    
    return mFileString;
}

#pragma mark - getter/setter

- (NSMutableArray *)hNameArray{
    if (!_hNameArray) {
        _hNameArray = [[NSMutableArray alloc] init];
    }
    return _hNameArray;
}

- (NSMutableArray *)mNameArray{
    if (!_mNameArray) {
        _mNameArray = [[NSMutableArray alloc] init];
    }
    return _mNameArray;
}

@end
